package edu.jd.software.web.backend.controller;

import edu.jd.software.web.backend.common.api.CommonResult;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import edu.jd.software.web.backend.dto.MinioUploadDto;
import edu.jd.software.web.backend.service.MinioService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;

import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;


@Controller
@Tag(name = "MinioController", description = "MinIO对象存储管理")
@RequestMapping("/minio")
public class MinioController {

    private static final Logger LOGGER = LoggerFactory.getLogger(MinioController.class);

    @Autowired
    private MinioService minioService;


    @Operation(summary = "上传文件",description = "MinIO的文件上传")
    @RequestMapping(value = "/upload",consumes = "multipart/form-data",method = RequestMethod.POST)
    @ResponseBody
    public CommonResult upload( @Parameter(description = "上传的文件", required = true,
            schema = @Schema(type = "string", format = "binary")) @RequestPart("file") MultipartFile file) {
        try {
            String filename = file.getOriginalFilename();
            // 设置存储对象名称(日期/文件名)
            String objectName = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + filename;

            String url = minioService.uploadFile(file, objectName);
            LOGGER.info("文件上传成功!");

            MinioUploadDto minioUploadDto = new MinioUploadDto();
            minioUploadDto.setName(filename);
            minioUploadDto.setUrl(url);

            return CommonResult.success(minioUploadDto);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("上传发生错误: {}！", e.getMessage());
        }
        return CommonResult.failed();
    }

    @GetMapping("/download")
    @Operation(summary = "流式下载", description = "适合大文件的分块下载")
    public StreamingResponseBody streamDownload(
            @RequestParam String  objectName,
            HttpServletResponse response) {

        return outputStream -> {
            try {
                String filename =  Paths.get(objectName).getFileName().toString();
                InputStream inputStream = minioService.downloadFile(objectName);
                response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
                response.setContentType("application/octet-stream");

                byte[] buffer = new byte[1024 * 1024]; // 1MB 缓冲区
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                    outputStream.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
                response.setStatus(SC_INTERNAL_SERVER_ERROR);
            }
        };
    }


    @Operation(description = "文件删除")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult delete(@RequestParam("objectName") String objectName) {
        try {
            minioService.deleteFile(objectName);
            return CommonResult.success(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.failed();
    }
}
